/*
 * Node.java
 *
 * Created on 13 maart 2008, 14:18
 *
 * @author wijnand.schepens@hogent.be
 */
package diagram;

import diagram.connections.Connection;
import connect.Type;
import diagram.locations.AbsoluteLocation;
import diagram.locations.Location;
import diagram.locations.FlexibleRelativeLocation;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class Node extends Graphical implements Serializable {

    private Location upperLeft;
    private Location lowerRight=null;
    private boolean selected = false;
    private String name;
    private String type;
    private Type valueType;       // null : none
    boolean mutable;
    // content...
    Location valueTargetPoint;
    Location callTargetPoint = null;
    List<Connection> callSources = new ArrayList<Connection>();
    protected int triangleWidth = 25;

    public Node() {

    }

    public Node(String name, String type, Type valueType, Location upperLeft) {
        //super(x, y);
        this.upperLeft = upperLeft;
        this.name = name;
        this.type = type;
        this.valueType = valueType;
        this.mutable = true;

    //this.valueTargetPoint = new CircleHandle(this, width, 0);
    }

    public void addCallSource() {
//              ConnectPoint source = new ConnectPoint(this);
//              ConnectPoint target = new DummyPoint(this);
//              callSources.add(new Connection(source, target));
        }

    //@Override
    public void paint(Graphics2D g) {
        Color oldColor = g.getColor();
        Stroke oldStroke = g.getStroke();

        int x = getUpperLeft().getX();
        int y = getUpperLeft().getY();
        int width = lowerRight.getX() - x;
        int height = lowerRight.getY() - y;

        g.setColor(Color.WHITE);
        g.fillRect(x, y, width, height);
        if (this.isSelected()) {
            g.setColor(Color.RED);
        } else {
            g.setColor(Color.BLACK);
        }

        g.setStroke(new BasicStroke(2));
        g.drawRect(x, y, width, height);
        g.drawLine(x, y+height/2, x+width, y+height/2);

        // g.setStroke(new BasicStroke(1));
        // g.drawLine(x, y + height / 3, x + width, y + height / 3);
        if (getName() != null) {
            drawCentered(g, getName(), new Rectangle(x, y, width, height / 3));
        }
        if (getType() != null) {
            drawCentered(g, getType(), new Rectangle(x, y + height / 3, width, height / 2));
        }
        //g.drawString(type, x + 3, y + hoogte - 3);

//        if (getValueType() != null) {
//            //g.drawLine(x + width, y + height / 3, x + width + triangleWidth, y + height * 2 / 3);
//           // g.drawLine(x + width, y + height, x + width + triangleWidth, y + height * 2 / 3);
//
//            if (mutable) {
//               // g.drawLine(x + width, y, x + width + triangleWidth, y);
//               // g.drawLine(x + width, y + height / 3, x + width + triangleWidth, y);
//                drawCentered(g, getValueType().getName(), new Rectangle(x + width, y + height / 3, triangleWidth * 2 / 3, height / 2));
//            }
//        }

//              if (valueTargetPoint != null)
//                      valueTargetPoint.paint(g);

        g.setColor(oldColor);
        g.setStroke(oldStroke);

    }

    protected static void drawCentered(Graphics g, String text, Rectangle bounds) {
        FontMetrics fm = g.getFontMetrics();
        Rectangle2D textBounds = fm.getStringBounds(text, g);

        int x = bounds.x + bounds.width / 2 - (int) (textBounds.getWidth() / 2);     // center
        int y = bounds.y + bounds.height - (int) textBounds.getHeight() / 2 + fm.getDescent();
        g.drawString(text, x, y);
    }

    public Rectangle getRectangle() {
        return new Rectangle(getX(), getY(), getWidth(), getHeight());
    }

    public boolean contains(int x, int y) {
        return getRectangle().contains(x, y);
    }

    public boolean isContainedIn(Rectangle rect) {
        return rect.contains(getRectangle());
    }

    public int getClickLocation(int y){
        int k= 0 ;
        if(y<getY()+getHeight()/2)
            k = 0;
        else if(y> getY()+getHeight()/2)
            k = 1;
        return k;
    }

    public int getX() {
        return getUpperLeft().getX();
    }

    public int getY() {
        return getUpperLeft().getY();
    }

    public void print() {
        System.out.println("X:" + getUpperLeft().getX() + "- Y:" + getUpperLeft().getY());
    }

    public int getWidth() {
        return lowerRight.getX() - getUpperLeft().getX();
    }

//      public void setWidth(int width)
//      {
//              if (width >= this.minWidth)
//                      this.width = width;
//      }
    public int getHeight() {
        return lowerRight.getY() - getUpperLeft().getY();
    }

//      public void setHeight(int height)
//      {
//              if (height >= this.minHeight)
//                      this.height = height;
//      }
    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public Location getUpperRight(){
        return new AbsoluteLocation(lowerRight.getX(),upperLeft.getY());
    }

    public Location getLowerLeft(){
        return new AbsoluteLocation(upperLeft.getX(),lowerRight.getY());
    }

    public Location getUpperLeft() {
        return upperLeft;
    }

    public void setUpperLeft(Location upperLeft) {
        this.upperLeft = upperLeft;
        if(lowerRight==null){
            System.out.println("in null lowerright");
            this.lowerRight = new FlexibleRelativeLocation(upperLeft, 100, 50);
        }
    }

    public Location getLowerRight() {
        return lowerRight;
    }

    public void setLowerRight(Location lowerRight) {
        this.lowerRight = lowerRight;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the type
     */
    public String getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(String type) {
        this.type = type;
    }

    /**
     * @return the valueType
     */
    public Type getValueType() {
        return valueType;
    }

    /**
     * @param valueType the valueType to set
     */
    public void setValueType(Type valueType) {
        this.valueType = valueType;
    }
}
